//----------------------------------------------------------------------------------------
// @Project Includes
#include "includes.h"

//----------------------------------------------------------------------------------------
// @Local Macro Define in the module

//----------------------------------------------------------------------------------------
// @Local Type defines in the module

//----------------------------------------------------------------------------------------
// @Global Variables define in the module
stc_protect_var_t  g_stcProtectVar;

//----------------------------------------------------------------------------------------
// @Prototypes of functions in the module
static void app_protect_tovCheck(void);
static void app_protect_tuvCheck(void);
static void app_protect_ovCheck(void);
static void app_protect_uvCheck(void);
static void app_protect_occCheck(void);
static void app_protect_ocdCheck(void);
static void app_protect_scvCheck(void);
static void app_protect_otcCheck(void);
static void app_protect_utcCheck(void);
static void app_protect_otdCheck(void);
static void app_protect_utdCheck(void);
static void app_protect_otmCheck(void);
static void app_protect_utmCheck(void);
static void app_protect_otaCheck(void);
static void app_protect_utaCheck(void);
static void app_protect_diffvolCheck(void);
static void app_protect_difftempCheck(void);
static void app_protect_soclowCheck(void);
static void app_protect_cellLineCheck(void);

static void app_protect_chgDsgControl(void);

//----------------------------------------------------------------------------------------
/**
 * @brief protect tov check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_tovCheck(void)
{
    if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_TOV) == 1)
		{
				switch (g_stcProtectVar.entov2Fg)
				{
						case PROTECT_STATE_NO:
								if (((g_stcVar.u32totalSumVolt/10) >= g_stcParm.stcSwProtect.u16tov2)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16tovt2++;
										if(g_stcProtectVar.u16tovt2 >= (g_stcParm.stcSwProtect.u16tovt2-100))
										{
												g_stcProtectVar.entov2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16tovt2 = 0;
												g_stcVar.unProtRank2.bit.tov = true;
												app_soc_setPackFull(true);
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16tovt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (((g_stcVar.u32totalSumVolt/10) <= g_stcParm.stcSwProtect.u16tovr2)||(srv_signal_getLoadIn()== true))
								{
										g_stcProtectVar.u16tovrt2++;
										if(g_stcProtectVar.u16tovrt2 >= (g_stcParm.stcSwProtect.u16tovrt2-100))
										{
												g_stcProtectVar.entov2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16tovrt2 = 0;
												g_stcVar.unProtRank2.bit.tov = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16tovrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}		
    if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_TOV) == 1)
		{
				switch (g_stcProtectVar.entov1Fg)
				{
						case PROTECT_STATE_NO:
								if (((g_stcVar.u32totalSumVolt/10) >= g_stcParm.stcSwProtect.u16tov1)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16tovt1++;
										if(g_stcProtectVar.u16tovt1 >= g_stcParm.stcSwProtect.u16tovt1)
										{
												g_stcProtectVar.entov1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16tovt1 = 0;
												g_stcVar.unProtRank1.bit.tov = true;
										}
								}
								else
								{
										g_stcProtectVar.u16tovt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.u32totalSumVolt/10) <= g_stcParm.stcSwProtect.u16tovr1)
								{
										g_stcProtectVar.u16tovrt1++;
										if(g_stcProtectVar.u16tovrt1 >= g_stcParm.stcSwProtect.u16tovrt1)
										{
												g_stcProtectVar.entov1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16tovrt1 = 0;
												g_stcVar.unProtRank1.bit.tov = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16tovrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}		

}

/**
 * @brief protect tuv check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_tuvCheck(void)
{
    if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_TUV) == 1)
		{
				switch (g_stcProtectVar.entuv2Fg)
				{
						case PROTECT_STATE_NO:
								if (((g_stcVar.u32totalSumVolt/10) <= g_stcParm.stcSwProtect.u16tuv2)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16tuvt2++;
										if(g_stcProtectVar.u16tuvt2 >= (g_stcParm.stcSwProtect.u16tuvt2-100))
										{
												g_stcProtectVar.entuv2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16tuvt2 = 0;
												g_stcVar.unProtRank2.bit.tuv = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16tuvt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (((g_stcVar.u32totalSumVolt/10) >= g_stcParm.stcSwProtect.u16tuvr2)||(srv_signal_getChargeIn()== true))
								{
										g_stcProtectVar.u16tuvrt2++;
										if(g_stcProtectVar.u16tuvrt2 >= (g_stcParm.stcSwProtect.u16tuvrt2-100))
										{
												g_stcProtectVar.entuv2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16tuvrt2 = 0;
												g_stcVar.unProtRank2.bit.tuv = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16tuvrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_TUV) == 1)	
		{		
				switch (g_stcProtectVar.entuv1Fg)
				{
						case PROTECT_STATE_NO:
								if (((g_stcVar.u32totalSumVolt/10) <= g_stcParm.stcSwProtect.u16tuv1)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16tuvt1++;
										if(g_stcProtectVar.u16tuvt1 >= g_stcParm.stcSwProtect.u16tuvt1)
										{
												g_stcProtectVar.entuv1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16tuvt1 = 0;
												g_stcVar.unProtRank1.bit.tuv = true;
										}
								}
								else
								{
										g_stcProtectVar.u16tuvt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.u32totalSumVolt/10) >= g_stcParm.stcSwProtect.u16tuvr1)
								{
										g_stcProtectVar.u16tuvrt1++;
										if(g_stcProtectVar.u16tuvrt1 >= g_stcParm.stcSwProtect.u16tuvrt1)
										{
												g_stcProtectVar.entuv1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16tuvrt1 = 0;
												g_stcVar.unProtRank1.bit.tuv = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16tuvrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}
			
}

/**
 * @brief protect ov check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_ovCheck(void)
{
		switch (g_stcProtectVar.enov3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getOV() == true)
						{
								g_stcProtectVar.enov3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.ov = true;
								app_soc_setPackFull(true);
								//return;
						}		
						break;			
				case PROTECT_STATE_YES:
						if ((g_stcVar.u16voltMax <= g_stcParm.stcSwProtect.u16ovr3)||
								((srv_signal_getLoadIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
						{
									app_afe_faultRemove();
									g_stcProtectVar.enov3Fg = PROTECT_STATE_NO;
									g_stcVar.unProtRank3.bit.ov = false;			
						}		
						break;
				default:
						break;	
		}
	
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_OV) == 1)
		{			
				switch (g_stcProtectVar.enov2Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.u16voltMax >= g_stcParm.stcSwProtect.u16ov2)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16ovt2++;
										if(g_stcProtectVar.u16ovt2 >= (g_stcParm.stcSwProtect.u16ovt2-100))
										{
												g_stcProtectVar.enov2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16ovt2 = 0;
												g_stcVar.unProtRank2.bit.ov = true;
												app_soc_setPackFull(true);
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16ovt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.u16voltMax <= g_stcParm.stcSwProtect.u16ovr2)||
										((srv_signal_getLoadIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16ovrt2++;
										if(g_stcProtectVar.u16ovrt2 >= (g_stcParm.stcSwProtect.u16ovrt2-100))
										{
												g_stcProtectVar.enov2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16ovrt2 = 0;
												g_stcVar.unProtRank2.bit.ov = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16ovrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_OV) == 1)
		{			
				switch (g_stcProtectVar.enov1Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.u16voltMax >= g_stcParm.stcSwProtect.u16ov1)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16ovt1++;
										if(g_stcProtectVar.u16ovt1 >= g_stcParm.stcSwProtect.u16ovt1)
										{
												g_stcProtectVar.enov1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16ovt1 = 0;
												g_stcVar.unProtRank1.bit.ov = true;
										}
								}
								else
								{
										g_stcProtectVar.u16ovt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.u16voltMax <= g_stcParm.stcSwProtect.u16ovr1)
								{
										g_stcProtectVar.u16ovrt1++;
										if(g_stcProtectVar.u16ovrt1 >= g_stcParm.stcSwProtect.u16ovrt1)
										{
												g_stcProtectVar.enov1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16ovrt1 = 0;
												g_stcVar.unProtRank1.bit.ov = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16ovrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}		

}

/**
 * @brief protect uv check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_uvCheck(void)
{
		switch (g_stcProtectVar.enuv3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getUV() == true)
						{
								g_stcProtectVar.enuv3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.uv = true;
								g_stcSoc.bfullChgCapAutoLearnFlag = true;
								//return;
						}	
						break;			
				case PROTECT_STATE_YES:
						if ((g_stcVar.u16voltMin >= g_stcParm.stcSwProtect.u16uvr3)||
								((srv_signal_getChargeIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
						{
								app_afe_faultRemove();
								g_stcProtectVar.enuv3Fg = PROTECT_STATE_NO;
								g_stcVar.unProtRank3.bit.uv = false;			
						}		
						break;
				default:
						break;	
		}		
	
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_UV) == 1)
		{
				switch (g_stcProtectVar.enuv2Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.u16voltMin <= g_stcParm.stcSwProtect.u16uv2)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16uvt2++;
										if(g_stcProtectVar.u16uvt2 >= (g_stcParm.stcSwProtect.u16uvt2-100))
										{
												g_stcProtectVar.enuv2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16uvt2 = 0;
												g_stcVar.unProtRank2.bit.uv = true;
												g_stcSoc.bfullChgCapAutoLearnFlag = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16uvt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.u16voltMin >= g_stcParm.stcSwProtect.u16uvr2)||
										((srv_signal_getChargeIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16uvrt2++;
										if(g_stcProtectVar.u16uvrt2 >= (g_stcParm.stcSwProtect.u16uvrt2-100))
										{
												g_stcProtectVar.enuv2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16uvrt2 = 0;
												g_stcVar.unProtRank2.bit.uv = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16uvrt2 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_UV) == 1)
		{
				switch (g_stcProtectVar.enuv1Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.u16voltMin <= g_stcParm.stcSwProtect.u16uv1)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16uvt1++;
										if(g_stcProtectVar.u16uvt1 >= g_stcParm.stcSwProtect.u16uvt1)
										{
												g_stcProtectVar.enuv1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16uvt1 = 0;
												g_stcVar.unProtRank1.bit.uv = true;
										}
								}
								else
								{
										g_stcProtectVar.u16uvt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.u16voltMin >= g_stcParm.stcSwProtect.u16uvr1)
								{
										g_stcProtectVar.u16uvrt1++;
										if(g_stcProtectVar.u16uvrt1 >= g_stcParm.stcSwProtect.u16uvrt1)
										{
												g_stcProtectVar.enuv1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16uvrt1 = 0;
												g_stcVar.unProtRank1.bit.uv = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16uvrt1 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		
}

/**
 * @brief protect occ check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_occCheck(void)
{
		switch (g_stcProtectVar.enocc3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getOCC() == true)
						{
								g_stcProtectVar.enocc3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.occ = true;
								//return;
						}
						else
						{
								g_stcProtectVar.u16occrt3 = 0;
						}
						break;			
				case PROTECT_STATE_YES:
						if ((srv_signal_getChargeIn()== false)&&(srv_contactor_getState(CNT_ALL) == false))
						{
							  g_stcProtectVar.u16occrt3++;
							  if(g_stcProtectVar.u16occrt3 >= g_stcParm.stcSwProtect.u16occrt3)
								{
									app_afe_faultRemove();
									g_stcProtectVar.enocc3Fg = PROTECT_STATE_NO;
									g_stcVar.unProtRank3.bit.occ = false;
									g_stcProtectVar.u16occrt3 = 0;
								}									
						}	
						else
						{
							g_stcProtectVar.u16occrt3 = 0;
						}						
						break;
				default:
						break;	
		}
				
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_OCC) == 1)
		{
				switch (g_stcProtectVar.enocc2Fg)
				{
						case PROTECT_STATE_NO:
								if (((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) >= g_stcParm.stcSwProtect.u16occv2)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16occt2++;
										if(g_stcProtectVar.u16occt2 >= g_stcParm.stcSwProtect.u16occt2)
										{
												g_stcProtectVar.enocc2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16occt2 = 0;
												g_stcVar.unProtRank2.bit.occ = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16occt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) <= g_stcParm.stcSwProtect.u16occrv2)||
										((srv_signal_getChargeIn()== false)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16occrt2++;
										if(g_stcProtectVar.u16occrt2 >= g_stcParm.stcSwProtect.u16occrt2)
										{
												g_stcProtectVar.enocc2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16occrt2 = 0;
												g_stcVar.unProtRank2.bit.occ = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16occrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_OCC) == 1)
		{
				switch (g_stcProtectVar.enocc1Fg)
				{
						case PROTECT_STATE_NO:
								if (((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) >= g_stcParm.stcSwProtect.u16occv1)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16occt1++;
										if(g_stcProtectVar.u16occt1 >= g_stcParm.stcSwProtect.u16occt1)
										{
												g_stcProtectVar.enocc1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16occt1 = 0;
												g_stcVar.unProtRank1.bit.occ = true;
										}
								}
								else
								{
										g_stcProtectVar.u16occt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) < g_stcParm.stcSwProtect.u16occv1)
								{
										g_stcProtectVar.u16occrt1++;
										if(g_stcProtectVar.u16occrt1 >= g_stcParm.stcSwProtect.u16occrt1)
										{
												g_stcProtectVar.enocc1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16occrt1 = 0;
												g_stcVar.unProtRank1.bit.occ = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16occrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}		
		
}

/**
 * @brief protect ocd check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_ocdCheck(void)
{
		switch (g_stcProtectVar.enocd3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getOCD() == true)
						{
								g_stcProtectVar.enocd3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.ocd = true;
								//return;
						}
						else
						{
							g_stcProtectVar.u16ocdrt3 = 0;
						}
						break;			
				case PROTECT_STATE_YES:
						if ((srv_signal_getLoadIn()== false)&&(srv_contactor_getState(CNT_ALL) == false))
						{
							  g_stcProtectVar.u16ocdrt3++;
								if(g_stcProtectVar.u16ocdrt3 >= g_stcParm.stcSwProtect.u16ocdrt3)
								{
									g_stcProtectVar.u16ocdrt3 = 0;
									app_afe_faultRemove();
									g_stcProtectVar.enocd3Fg = PROTECT_STATE_NO;
									g_stcVar.unProtRank3.bit.ocd = false;	
								}									
						}
						else
						{
							g_stcProtectVar.u16ocdrt3 = 0;
						}
						break;
				default:
						break;	
		}		
	
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_OCD) == 1)
		{
				switch (g_stcProtectVar.enocd2Fg)
				{
						case PROTECT_STATE_NO:
								if (((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) >= g_stcParm.stcSwProtect.u16ocdv2)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16ocdt2++;
										if(g_stcProtectVar.u16ocdt2 >= (g_stcParm.stcSwProtect.u16ocdt2-100))
										{
												g_stcProtectVar.enocd2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16ocdt2 = 0;
												g_stcVar.unProtRank2.bit.ocd = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16ocdt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) <= g_stcParm.stcSwProtect.u16ocdrv2)||
										((srv_signal_getLoadIn()== false)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16ocdrt2++;
										if(g_stcProtectVar.u16ocdrt2 >= g_stcParm.stcSwProtect.u16ocdrt2)
										{
												g_stcProtectVar.enocd2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16ocdrt2 = 0;
												g_stcVar.unProtRank2.bit.ocd = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16ocdrt2 = 0;
								}			
								break;
						default:
								break;	
				}	
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_OCD) == 1)
		{
				switch (g_stcProtectVar.enocd1Fg)
				{
						case PROTECT_STATE_NO:
								if (((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) >= g_stcParm.stcSwProtect.u16ocdv1)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16ocdt1++;
										if(g_stcProtectVar.u16ocdt1 >= g_stcParm.stcSwProtect.u16ocdt1)
										{
												g_stcProtectVar.enocd1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16ocdt1 = 0;
												g_stcVar.unProtRank1.bit.ocd = true;
										}
								}
								else
								{
										g_stcProtectVar.u16ocdt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((abs(g_stcVar.i32avgCurrent)/CURRENT_CALC_RATE) < g_stcParm.stcSwProtect.u16ocdv1)
								{
										g_stcProtectVar.u16ocdrt1++;
										if(g_stcProtectVar.u16ocdrt1 >= g_stcParm.stcSwProtect.u16ocdrt1)
										{
												g_stcProtectVar.enocd1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16ocdrt1 = 0;
												g_stcVar.unProtRank1.bit.ocd = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16ocdrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}		
}

/**
 * @brief protect ocd check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_scvCheck(void)
{
		static uint16_t u16timeout = 0;
	
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_SCV) == 1)	
		{
				switch (g_stcProtectVar.enscv3Fg)
				{
						case PROTECT_STATE_NO:
								if (srv_afe_getSC() == true)
								{
										g_stcProtectVar.enscv3Fg = PROTECT_STATE_YES;
										g_stcVar.unProtRank3.bit.sc = true;            
								}	
								else
								{
									 u16timeout = 0;
								}								
								break;			
						case PROTECT_STATE_YES:
								if ((srv_signal_getLoadIn()== false)&&
										(srv_signal_getChargeIn()== false)&&
										(srv_contactor_getState(CNT_ALL) == false))
								{
									  u16timeout++;
									  if (u16timeout >= 100)
										{		
											u16timeout = 0;											
											app_afe_faultRemove();
											g_stcProtectVar.enscv3Fg = PROTECT_STATE_NO;
											g_stcVar.unProtRank3.bit.sc = false;
										}											
								}	
								else
								{
									 u16timeout = 0;
								}									
								break;
						default:
								break;	
				}
		}		
}

/**
 * @brief protect otc check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_otcCheck(void)
{
		switch (g_stcProtectVar.enotc3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getOTC() == true)
						{
								g_stcProtectVar.enotc3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.otc = true;
								//return;
						}			
						break;			
				case PROTECT_STATE_YES:
						if ((g_stcVar.i8tempMax <= g_stcParm.stcSwProtect.i16otcr3)||
								((srv_signal_getLoadIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
						{
								app_afe_faultRemove();
								g_stcProtectVar.enotc3Fg = PROTECT_STATE_NO;
								g_stcVar.unProtRank3.bit.otc = false;			
						}			
						break;
				default:
						break;	
		}	
		
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_OTC) == 1)	
		{
				switch (g_stcProtectVar.enotc2Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMax >= g_stcParm.stcSwProtect.i16otc2)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16otct2++;
										if(g_stcProtectVar.u16otct2 >= g_stcParm.stcSwProtect.u16otct2)
										{
												g_stcProtectVar.enotc2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otct2 = 0;
												g_stcVar.unProtRank2.bit.otc = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16otct2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.i8tempMax <= g_stcParm.stcSwProtect.i16otcr2)||
										((srv_signal_getLoadIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16otcrt2++;
										if(g_stcProtectVar.u16otcrt2 >= g_stcParm.stcSwProtect.u16otcrt2)
										{
												g_stcProtectVar.enotc2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otcrt2 = 0;
												g_stcVar.unProtRank2.bit.otc = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otcrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_OTC) == 1)	
		{			
				switch (g_stcProtectVar.enotc1Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMax >= g_stcParm.stcSwProtect.i16otc1)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16otct1++;
										if(g_stcProtectVar.u16otct1 >= g_stcParm.stcSwProtect.u16otct1)
										{
												g_stcProtectVar.enotc1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otct1 = 0;
												g_stcVar.unProtRank1.bit.otc = true;
										}
								}
								else
								{
										g_stcProtectVar.u16otct1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8tempMax <= g_stcParm.stcSwProtect.i16otcr1)
								{
										g_stcProtectVar.u16otcrt1++;
										if(g_stcProtectVar.u16otcrt1 >= g_stcParm.stcSwProtect.u16otcrt1)
										{
												g_stcProtectVar.enotc1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otcrt1 = 0;
												g_stcVar.unProtRank1.bit.otc = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otcrt1 = 0;
								}			
								break;
						default:
								break;	
				}	
		}				
}

/**
 * @brief protect utc check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_utcCheck(void)
{
		switch (g_stcProtectVar.enutc3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getUTC() == true)
						{
								g_stcProtectVar.enutc3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.utc = true;
								//return;
						}			
						break;			
				case PROTECT_STATE_YES:
						if ((g_stcVar.i8tempMin >= g_stcParm.stcSwProtect.i16utcr3)||
								((srv_signal_getLoadIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
						{
								app_afe_faultRemove();
								g_stcProtectVar.enutc3Fg = PROTECT_STATE_NO;
								g_stcVar.unProtRank3.bit.utc = false;			
						}
						break;
				default:
						break;	
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_UTC) == 1)	
		{
				switch (g_stcProtectVar.enutc2Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMin <= g_stcParm.stcSwProtect.i16utc2)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16utct2++;
										if(g_stcProtectVar.u16utct2 >= g_stcParm.stcSwProtect.u16utct2)
										{
												g_stcProtectVar.enutc2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utct2 = 0;
												g_stcVar.unProtRank2.bit.utc = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16utct2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.i8tempMin >= g_stcParm.stcSwProtect.i16utcr2)||
										((srv_signal_getLoadIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16utcrt2++;
										if(g_stcProtectVar.u16utcrt2 >= g_stcParm.stcSwProtect.u16utcrt2)
										{
												g_stcProtectVar.enutc2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utcrt2 = 0;
												g_stcVar.unProtRank2.bit.utc = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utcrt2 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_UTC) == 1)
		{			
				switch (g_stcProtectVar.enutc1Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMin <= g_stcParm.stcSwProtect.i16utc1)&&(g_stcState.enstate == SST_CHG))
								{
										g_stcProtectVar.u16utct1++;
										if(g_stcProtectVar.u16utct1 >= g_stcParm.stcSwProtect.u16utct1)
										{
												g_stcProtectVar.enutc1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utct1 = 0;
												g_stcVar.unProtRank1.bit.utc = true;
										}
								}
								else
								{
										g_stcProtectVar.u16utct1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8tempMin >= g_stcParm.stcSwProtect.i16utcr1)
								{
										g_stcProtectVar.u16utcrt1++;
										if(g_stcProtectVar.u16utcrt1 >= g_stcParm.stcSwProtect.u16utcrt1)
										{
												g_stcProtectVar.enutc1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utcrt1 = 0;
												g_stcVar.unProtRank1.bit.utc = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utcrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}		
}

/**
 * @brief protect otd check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_otdCheck(void)
{
		switch (g_stcProtectVar.enotd3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getOTD() == true)
						{
								g_stcProtectVar.enotd3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.otd = true;
								//return;
						}		
						break;			
				case PROTECT_STATE_YES:
						if ((g_stcVar.i8tempMax <= g_stcParm.stcSwProtect.i16otdr3)||
								((srv_signal_getChargeIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
						{
								app_afe_faultRemove();
								g_stcProtectVar.enotd3Fg = PROTECT_STATE_NO;
								g_stcVar.unProtRank3.bit.otd = false;			
						}		
						break;
				default:
						break;	
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_OTD) == 1)	
		{			
				switch (g_stcProtectVar.enotd2Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMax >= g_stcParm.stcSwProtect.i16otd2)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16otdt2++;
										if(g_stcProtectVar.u16otdt2 >= g_stcParm.stcSwProtect.u16otdt2)
										{
												g_stcProtectVar.enotd2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otdt2 = 0;
												g_stcVar.unProtRank2.bit.otd = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16otdt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.i8tempMax <= g_stcParm.stcSwProtect.i16otdr2)||
										((srv_signal_getChargeIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16otdrt2++;
										if(g_stcProtectVar.u16otdrt2 >= g_stcParm.stcSwProtect.u16otdrt2)
										{
												g_stcProtectVar.enotd2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otdrt2 = 0;
												g_stcVar.unProtRank2.bit.otd = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otdrt2 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_OTD) == 1)	
		{
				switch (g_stcProtectVar.enotd1Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMax >= g_stcParm.stcSwProtect.i16otd1)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16otdt1++;
										if(g_stcProtectVar.u16otdt1 >= g_stcParm.stcSwProtect.u16otdt1)
										{
												g_stcProtectVar.enotd1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otdt1 = 0;
												g_stcVar.unProtRank1.bit.otd = true;
										}
								}
								else
								{
										g_stcProtectVar.u16otdt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8tempMax <= g_stcParm.stcSwProtect.i16otdr1)
								{
										g_stcProtectVar.u16otdrt1++;
										if(g_stcProtectVar.u16otdrt1 >= g_stcParm.stcSwProtect.u16otdrt1)
										{
												g_stcProtectVar.enotd1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otdrt1 = 0;
												g_stcVar.unProtRank1.bit.otd = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otdrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}			
}

/**
 * @brief protect utd check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_utdCheck(void)
{
		switch (g_stcProtectVar.enutd3Fg)
		{
				case PROTECT_STATE_NO:
						if (srv_afe_getUTD() == true)
						{
								g_stcProtectVar.enutd3Fg = PROTECT_STATE_YES;
								g_stcVar.unProtRank3.bit.utd = true;
								//return;
						}			
						break;			
				case PROTECT_STATE_YES:
						if ((g_stcVar.i8tempMin >= g_stcParm.stcSwProtect.i16utdr3)||
								((srv_signal_getChargeIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
						{
								app_afe_faultRemove();
								g_stcProtectVar.enutd3Fg = PROTECT_STATE_NO;
								g_stcVar.unProtRank3.bit.utd = false;			
						}		
						break;
				default:
						break;	
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_UTD) == 1)	
		{			
				switch (g_stcProtectVar.enutd2Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMin <= g_stcParm.stcSwProtect.i16utd2)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16utdt2++;
										if(g_stcProtectVar.u16utdt2 >= g_stcParm.stcSwProtect.u16utdt2)
										{
												g_stcProtectVar.enutd2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utdt2 = 0;
												g_stcVar.unProtRank2.bit.utd = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16utdt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcVar.i8tempMin >= g_stcParm.stcSwProtect.i16utdr2)||
										((srv_signal_getChargeIn()== true)&&(srv_contactor_getState(CNT_ALL) == false)))
								{
										g_stcProtectVar.u16utdrt2++;
										if(g_stcProtectVar.u16utdrt2 >= g_stcParm.stcSwProtect.u16utdrt2)
										{
												g_stcProtectVar.enutd2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utdrt2 = 0;
												g_stcVar.unProtRank2.bit.utd = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utdrt2 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_UTD) == 1)
		{			
				switch (g_stcProtectVar.enutd1Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcVar.i8tempMin <= g_stcParm.stcSwProtect.i16utd1)&&(g_stcState.enstate == SST_DSG))
								{
										g_stcProtectVar.u16utdt1++;
										if(g_stcProtectVar.u16utdt1 >= g_stcParm.stcSwProtect.u16utdt1)
										{
												g_stcProtectVar.enutd1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utdt1 = 0;
												g_stcVar.unProtRank1.bit.utd = true;
										}
								}
								else
								{
										g_stcProtectVar.u16utdt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8tempMin >= g_stcParm.stcSwProtect.i16utdr1)
								{
										g_stcProtectVar.u16utdrt1++;
										if(g_stcProtectVar.u16utdrt1 >= g_stcParm.stcSwProtect.u16utdrt1)
										{
												g_stcProtectVar.enutd1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utdrt1 = 0;
												g_stcVar.unProtRank1.bit.utd = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utdrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}		
		
}

/**
 * @brief protect otcdm check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_otmCheck(void)
{
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_OTM) == 1)	
		{			
				switch (g_stcProtectVar.enotcdm2Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8mosTemp >= g_stcParm.stcSwProtect.i16otcdm2)
								{
										g_stcProtectVar.u16otcdmt2++;
										if(g_stcProtectVar.u16otcdmt2 >= g_stcParm.stcSwProtect.u16otcdmt2)
										{
												g_stcProtectVar.enotcdm2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otcdmt2 = 0;
												g_stcVar.unProtRank2.bit.otcdm = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16otcdmt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8mosTemp <= g_stcParm.stcSwProtect.i16otcdmr2)
								{
										g_stcProtectVar.u16otcdmrt2++;
										if(g_stcProtectVar.u16otcdmrt2 >= g_stcParm.stcSwProtect.u16otcdmrt2)
										{
												g_stcProtectVar.enotcdm2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otcdmrt2 = 0;
												g_stcVar.unProtRank2.bit.otcdm = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otcdmrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_OTM) == 1)
		{			
				switch (g_stcProtectVar.enotcdm1Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8mosTemp >= g_stcParm.stcSwProtect.i16otcdm1)
								{
										g_stcProtectVar.u16otcdmt1++;
										if(g_stcProtectVar.u16otcdmt1 >= g_stcParm.stcSwProtect.u16otcdmt1)
										{
												g_stcProtectVar.enotcdm1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otcdmt1 = 0;
												g_stcVar.unProtRank1.bit.otcdm = true;
										}
								}
								else
								{
										g_stcProtectVar.u16otcdmt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8mosTemp <= g_stcParm.stcSwProtect.i16otcdmr1)
								{
										g_stcProtectVar.u16otcdmrt1++;
										if(g_stcProtectVar.u16otcdmrt1 >= g_stcParm.stcSwProtect.u16otcdmrt1)
										{
												g_stcProtectVar.enotcdm1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otcdmrt1 = 0;
												g_stcVar.unProtRank1.bit.otcdm = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otcdmrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		
}

/**
 * @brief protect utcdm check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_utmCheck(void)
{
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_UTM) == 1)	
		{			
				switch (g_stcProtectVar.enutcdm2Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8mosTemp <= g_stcParm.stcSwProtect.i16utcdm2)
								{
										g_stcProtectVar.u16utcdmt2++;
										if(g_stcProtectVar.u16utcdmt2 >= g_stcParm.stcSwProtect.u16utcdmt2)
										{
												g_stcProtectVar.enutcdm2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utcdmt2 = 0;
												g_stcVar.unProtRank2.bit.utcdm = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16utcdmt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8mosTemp >= g_stcParm.stcSwProtect.i16utcdmr2)
								{
										g_stcProtectVar.u16utcdmrt2++;
										if(g_stcProtectVar.u16utcdmrt2 >= g_stcParm.stcSwProtect.u16utcdmrt2)
										{
												g_stcProtectVar.enutcdm2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utcdmrt2 = 0;
												g_stcVar.unProtRank2.bit.utcdm = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utcdmrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_UTM) == 1)	
		{			
				switch (g_stcProtectVar.enutcdm1Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8mosTemp <= g_stcParm.stcSwProtect.i16utcdm1)
								{
										g_stcProtectVar.u16utcdmt1++;
										if(g_stcProtectVar.u16utcdmt1 >= g_stcParm.stcSwProtect.u16utcdmt1)
										{
												g_stcProtectVar.enutcdm1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utcdmt1 = 0;
												g_stcVar.unProtRank1.bit.utcdm = true;
										}
								}
								else
								{
										g_stcProtectVar.u16utcdmt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8mosTemp >= g_stcParm.stcSwProtect.i16utcdmr1)
								{
										g_stcProtectVar.u16utcdmrt1++;
										if(g_stcProtectVar.u16utcdmrt1 >= g_stcParm.stcSwProtect.u16utcdmrt1)
										{
												g_stcProtectVar.enutcdm1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utcdmrt1 = 0;
												g_stcVar.unProtRank1.bit.utcdm = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utcdmrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		
}

/**
 * @brief protect otamb check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_otaCheck(void)
{
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_OTA) == 1)
		{			
				switch (g_stcProtectVar.enotamb2Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8ambTemp >= g_stcParm.stcSwProtect.i16otamb2)
								{
										g_stcProtectVar.u16otambt2++;
										if(g_stcProtectVar.u16otambt2 >= g_stcParm.stcSwProtect.u16otambt2)
										{
												g_stcProtectVar.enotamb2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otambt2 = 0;
												g_stcVar.unProtRank2.bit.otamb = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16otambt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8ambTemp <= g_stcParm.stcSwProtect.i16otambr2)
								{
										g_stcProtectVar.u16otambrt2++;
										if(g_stcProtectVar.u16otambrt2 >= g_stcParm.stcSwProtect.u16otambrt2)
										{
												g_stcProtectVar.enotamb2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otambrt2 = 0;
												g_stcVar.unProtRank2.bit.otamb = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otambrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_OTA) == 1)
		{			
				switch (g_stcProtectVar.enotamb1Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8ambTemp >= g_stcParm.stcSwProtect.i16otamb1)
								{
										g_stcProtectVar.u16otambt1++;
										if(g_stcProtectVar.u16otambt1 >= g_stcParm.stcSwProtect.u16otambt1)
										{
												g_stcProtectVar.enotamb1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16otambt1 = 0;
												g_stcVar.unProtRank1.bit.otamb = true;
										}
								}
								else
								{
										g_stcProtectVar.u16otambt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8ambTemp <= g_stcParm.stcSwProtect.i16otambr1)
								{
										g_stcProtectVar.u16otambrt1++;
										if(g_stcProtectVar.u16otambrt1 >= g_stcParm.stcSwProtect.u16otambrt1)
										{
												g_stcProtectVar.enotamb1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16otambrt1 = 0;
												g_stcVar.unProtRank1.bit.otamb = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16otambrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		
}

/**
 * @brief protect utcdm check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_utaCheck(void)
{
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_UTA) == 1)
		{
				switch (g_stcProtectVar.enutamb2Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8ambTemp <= g_stcParm.stcSwProtect.i16utamb2)
								{
										g_stcProtectVar.u16utambt2++;
										if(g_stcProtectVar.u16utambt2 >= g_stcParm.stcSwProtect.u16utambt2)
										{
												g_stcProtectVar.enutamb2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utambt2 = 0;
												g_stcVar.unProtRank2.bit.utamb = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16utambt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8ambTemp >= g_stcParm.stcSwProtect.i16utambr2)
								{
										g_stcProtectVar.u16utambrt2++;
										if(g_stcProtectVar.u16utambrt2 >= g_stcParm.stcSwProtect.u16utambrt2)
										{
												g_stcProtectVar.enutamb2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utambrt2 = 0;
												g_stcVar.unProtRank2.bit.utamb = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utambrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_UTA) == 1)
		{
				switch (g_stcProtectVar.enutamb1Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.i8ambTemp <= g_stcParm.stcSwProtect.i16utamb1)
								{
										g_stcProtectVar.u16utambt1++;
										if(g_stcProtectVar.u16utambt1 >= g_stcParm.stcSwProtect.u16utambt1)
										{
												g_stcProtectVar.enutamb1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16utambt1 = 0;
												g_stcVar.unProtRank1.bit.utamb = true;
										}
								}
								else
								{
										g_stcProtectVar.u16utambt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.i8ambTemp >= g_stcParm.stcSwProtect.i16utambr1)
								{
										g_stcProtectVar.u16utambrt1++;
										if(g_stcProtectVar.u16utambrt1 >= g_stcParm.stcSwProtect.u16utambrt1)
										{
												g_stcProtectVar.enutamb1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16utambrt1 = 0;
												g_stcVar.unProtRank1.bit.utamb = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16utambrt1 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		
}

/**
 * @brief protect diffvol check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_diffvolCheck(void)
{
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_DIFV) == 1)
		{
				switch (g_stcProtectVar.endiffvol2Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.u16voltDiff >= g_stcParm.stcSwProtect.u16diffvol2)
								{
										g_stcProtectVar.u16diffvolt2++;
										if(g_stcProtectVar.u16diffvolt2 >= g_stcParm.stcSwProtect.u16diffvolt2)
										{
												g_stcProtectVar.endiffvol2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16diffvolt2 = 0;
												g_stcVar.unProtRank2.bit.diffvol = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16diffvolt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.u16voltDiff <= g_stcParm.stcSwProtect.u16diffvolr2)
								{
										g_stcProtectVar.u16diffvolrt2++;
										if(g_stcProtectVar.u16diffvolrt2 >= g_stcParm.stcSwProtect.u16diffvolrt2)
										{
												g_stcProtectVar.endiffvol2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16diffvolrt2 = 0;
												g_stcVar.unProtRank2.bit.diffvol = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16diffvolrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_DIFV) == 1)
		{
				switch (g_stcProtectVar.endiffvol1Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.u16voltDiff >= g_stcParm.stcSwProtect.u16diffvol1)
								{
										g_stcProtectVar.u16diffvolt1++;
										if(g_stcProtectVar.u16diffvolt1 >= g_stcParm.stcSwProtect.u16diffvolt1)
										{
												g_stcProtectVar.endiffvol1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16diffvolt1 = 0;
												g_stcVar.unProtRank1.bit.diffvol = true;
										}
								}
								else
								{
										g_stcProtectVar.u16diffvolt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.u16voltDiff <= g_stcParm.stcSwProtect.u16diffvolr1)
								{
										g_stcProtectVar.u16diffvolrt1++;
										if(g_stcProtectVar.u16diffvolrt1 >= g_stcParm.stcSwProtect.u16diffvolrt1)
										{
												g_stcProtectVar.endiffvol1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16diffvolrt1 = 0;
												g_stcVar.unProtRank1.bit.diffvol = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16diffvolrt1 = 0;
								}			
								break;
						default:
								break;	
				}
		}		
		
}

/**
 * @brief protect difftemp check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_difftempCheck(void)
{
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_DIFT) == 1)
		{
				switch (g_stcProtectVar.endifftemp2Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.u8tempDel >= g_stcParm.stcSwProtect.u16difftemp2)
								{
										g_stcProtectVar.u16difftempt2++;
										if(g_stcProtectVar.u16difftempt2 >= g_stcParm.stcSwProtect.u16difftempt2)
										{
												g_stcProtectVar.endifftemp2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16difftempt2 = 0;
												g_stcVar.unProtRank2.bit.difftemp = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16difftempt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.u8tempDel <= g_stcParm.stcSwProtect.u16difftempr2)
								{
										g_stcProtectVar.u16difftemprt2++;
										if(g_stcProtectVar.u16difftemprt2 >= g_stcParm.stcSwProtect.u16difftemprt2)
										{
												g_stcProtectVar.endifftemp2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16difftemprt2 = 0;
												g_stcVar.unProtRank2.bit.difftemp = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16difftemprt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_DIFT) == 1)
		{
				switch (g_stcProtectVar.endifftemp1Fg)
				{
						case PROTECT_STATE_NO:
								if (g_stcVar.u8tempDel >= g_stcParm.stcSwProtect.u16difftemp1)
								{
										g_stcProtectVar.u16difftempt1++;
										if(g_stcProtectVar.u16difftempt1 >= g_stcParm.stcSwProtect.u16difftempt1)
										{
												g_stcProtectVar.endifftemp1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16difftempt1 = 0;
												g_stcVar.unProtRank1.bit.difftemp = true;
										}
								}
								else
								{
										g_stcProtectVar.u16difftempt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if (g_stcVar.u8tempDel <= g_stcParm.stcSwProtect.u16difftempr1)
								{
										g_stcProtectVar.u16difftemprt1++;
										if(g_stcProtectVar.u16difftemprt1 >= g_stcParm.stcSwProtect.u16difftemprt1)
										{
												g_stcProtectVar.endifftemp1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16difftemprt1 = 0;
												g_stcVar.unProtRank1.bit.difftemp = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16difftemprt1 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		
}

/**
 * @brief protect soclow check
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_soclowCheck(void)
{
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_SOCLOW) == 1)
		{
				switch (g_stcProtectVar.ensoclow2Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcSoc.stcdata.u32displayValue/10000) <= g_stcParm.stcSwProtect.u16soclow2)
								{
										g_stcProtectVar.u16soclowt2++;
										if(g_stcProtectVar.u16soclowt2 >= g_stcParm.stcSwProtect.u16soclowt2)
										{
												g_stcProtectVar.ensoclow2Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16soclowt2 = 0;
												g_stcVar.unProtRank2.bit.soclow = true;
										}
										return;
								}
								else
								{
										g_stcProtectVar.u16soclowt2 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcSoc.stcdata.u32displayValue/10000) > g_stcParm.stcSwProtect.u16soclowr2)
								{
										g_stcProtectVar.u16soclowrt2++;
										if(g_stcProtectVar.u16soclowrt2 >= g_stcParm.stcSwProtect.u16soclowrt2)
										{
												g_stcProtectVar.ensoclow2Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16soclowrt2 = 0;
												g_stcVar.unProtRank2.bit.soclow = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16soclowrt2 = 0;
								}			
								break;
						default:
								break;	
				}
		}
		if (GetBit(g_stcParm.stcConfig.u32rank1Func,RANKFUNC_SOCLOW) == 1)
		{
				switch (g_stcProtectVar.ensoclow1Fg)
				{
						case PROTECT_STATE_NO:
								if ((g_stcSoc.stcdata.u32displayValue/10000) <= g_stcParm.stcSwProtect.u16soclow1)
								{
										g_stcProtectVar.u16soclowt1++;
										if(g_stcProtectVar.u16soclowt1 >= g_stcParm.stcSwProtect.u16soclowt1)
										{
												g_stcProtectVar.ensoclow1Fg = PROTECT_STATE_YES;
												g_stcProtectVar.u16soclowt1 = 0;
												g_stcVar.unProtRank1.bit.soclow = true;
										}
								}
								else
								{
										g_stcProtectVar.u16soclowt1 = 0;
								}			
								break;			
						case PROTECT_STATE_YES:
								if ((g_stcSoc.stcdata.u32displayValue/10000) > g_stcParm.stcSwProtect.u16soclowr1)
								{
										g_stcProtectVar.u16soclowrt1++;
										if(g_stcProtectVar.u16soclowrt1 >= g_stcParm.stcSwProtect.u16soclowrt1)
										{
												g_stcProtectVar.ensoclow1Fg = PROTECT_STATE_NO;
												g_stcProtectVar.u16soclowrt1 = 0;
												g_stcVar.unProtRank1.bit.soclow = false;			
										}
								}
								else
								{
										g_stcProtectVar.u16soclowrt1 = 0;
								}			
								break;
						default:
								break;	
				}	
		}		
		
}

/**
 * @brief  protect cell line check
 * @param   
 * @return 
 * @note   Note
 */
static void app_protect_cellLineCheck(void)
{
    uint8_t  u8cellpos = 0;    /* Cell position */
    uint16_t u16vcellfirst = 0; /* Cell voltage of first one */
    uint16_t u16vcelllast = 0;  /* Cell voltage of last one */
    bool_t  blineflag = false; 

    /*cell volt line open fault check*/
    for (u8cellpos = 1; u8cellpos < g_stcParm.stcConfig.u8cellS; u8cellpos++)
    {
				u16vcellfirst = g_stcVar.u16cellVolt[u8cellpos];
				u16vcelllast  = g_stcVar.u16cellVolt[u8cellpos - 1];
				#if 0
				if (((u16vcellfirst > CELL_VOLT_HIGH) && (u16vcelllast < CELL_VOLT_LOW))
			      || ((u16vcellfirst < CELL_VOLT_LOW) && (u16vcelllast > CELL_VOLT_HIGH)))
				{
						blineflag = true;					
				}
				else
				{
						//blineflag = false;
				}
				#else
				if ((u16vcellfirst < CELL_VOLT_LOW) && (u16vcelllast < CELL_VOLT_LOW))
				{
						blineflag = true;					
				}
				else
				{
						//blineflag = false;
				}		
				#endif
    }
		if (GetBit(g_stcParm.stcConfig.u32rank2Func,RANKFUNC_INS) == 1)
		{
				switch (g_stcProtectVar.enline3Fg)
				{
						case PROTECT_STATE_NO:
								if (blineflag == true)
								{
										g_stcProtectVar.enline3Fg = PROTECT_STATE_YES;
										g_stcVar.unProtRank3.bit.line = true; 
										SYSTEM_DEBUG("SYS:<< *****line fault******\r\n");								
								}	
								break;			
						case PROTECT_STATE_YES:
								if (blineflag == false)
								{
										g_stcProtectVar.enline3Fg = PROTECT_STATE_NO;
										g_stcVar.unProtRank3.bit.line = false;            
								}			
								break;
						default:
								break;	
				}
		}			
}

static void app_protect_fullchgCheck(void)
{
	if(g_stcProtectVar.enfullchgFg == PROTECT_STATE_YES)
	{
		if((srv_signal_getChargeIn()== false)&&(srv_contactor_getState(CNT_ALL) == false))
		{
			g_stcProtectVar.fullchgrt++;
			if(g_stcProtectVar.fullchgrt >= 100)
			{
				g_stcProtectVar.enfullchgFg = PROTECT_STATE_NO;
				g_stcVar.unProtRank3.bit.full = false; 
			}											
		}
	}
	else
	{
			g_stcProtectVar.fullchgrt = 0;
	}
}

 /**
 * @brief protect mos control
 * @param  none
 * @return none
 * @note   none
 */
static void app_protect_chgDsgControl(void)
{
    if( g_stcProtectVar.entov2Fg
				|(g_stcProtectVar.enov2Fg&&(g_stcVar.unProtRank3.bit.line == false))
        |g_stcProtectVar.enocc2Fg     
        |g_stcProtectVar.enotc2Fg
        |g_stcProtectVar.enutc2Fg
				|g_stcProtectVar.enov3Fg 				
        |g_stcProtectVar.enocc3Fg     
        |g_stcProtectVar.enotc3Fg
        |g_stcProtectVar.enutc3Fg				
        |g_stcProtectVar.enscv3Fg 
				|g_stcProtectVar.enotcdm2Fg
				|g_stcProtectVar.enfullchgFg
        |(g_stcVar.bchgMosCtl == false)				
				|(g_stcVar.bchgMosCmdCtl == false)						
        )
    {
        if(g_stcVar.bchgAfeMosCtl == true)
        {
						g_stcVar.bchgAfeMosCtl = false;
            g_stcState.enstate = SST_INIT;
        }	
    }
    else
    {
        if(g_stcVar.bchgAfeMosCtl == false)
        {
						g_stcVar.bchgAfeMosCtl = true;
        }		
    }

    if( g_stcProtectVar.entuv2Fg    
        |(g_stcProtectVar.enuv2Fg&&(g_stcVar.unProtRank3.bit.line == false))	
				|g_stcProtectVar.enocd2Fg     
        |g_stcProtectVar.enotd2Fg
        |g_stcProtectVar.enutd2Fg
				|g_stcProtectVar.enuv3Fg 				
        |g_stcProtectVar.enocd3Fg     
        |g_stcProtectVar.enotd3Fg
        |g_stcProtectVar.enutd3Fg
        |g_stcProtectVar.enscv3Fg
				|g_stcProtectVar.enotcdm2Fg
        |(g_stcVar.bdsgMosCtl == false)		
				|(g_stcVar.bdsgMosCmdCtl == false)							
        ) 			
    {
        if(g_stcVar.bdsgAfeMosCtl == true)
        {
						g_stcVar.bdsgAfeMosCtl = false;
            g_stcState.enstate = SST_INIT;
        }
    }
    else
    {
        if(g_stcVar.bdsgAfeMosCtl == false)
        {
						g_stcVar.bdsgAfeMosCtl = true;
        }
    }
}

/**
 * @brief protect check
 * @param  none 
 * @return none
 * @note   none
 */
void app_protect_check(void)
{
    if (g_stcVar.u32totalSumVolt == 0 )
    {
        return ;
    }	
		
    if (g_stcVar.binitFinishFlg == false )
    {
        return ;
    }
		
		if (g_stcParm.stcConfig.u8swProtectEn == true)
		{
				app_protect_tovCheck();
				app_protect_tuvCheck();
				app_protect_ovCheck();
				app_protect_uvCheck();
				app_protect_occCheck();
				app_protect_ocdCheck();
				app_protect_scvCheck();
				app_protect_otcCheck();
				app_protect_utcCheck();
				app_protect_otdCheck();
				app_protect_utdCheck();
				app_protect_otmCheck();
				app_protect_utmCheck();
				app_protect_otaCheck();
				app_protect_utaCheck();
				app_protect_diffvolCheck();
				app_protect_difftempCheck();
				app_protect_soclowCheck();
				app_protect_cellLineCheck();
			  app_protect_fullchgCheck();			
		}			
    app_protect_chgDsgControl();
		app_afe_checkFlag();
    
}

/**
 * @brief protect init
 * @param  none
 * @return none
 * @note   none
 */
void app_protect_init(void)
{
    /* Init the varible */
    (void)memset((void *)&g_stcProtectVar, 0, sizeof(g_stcProtectVar));	
}

// =======================================================================================
// End of file.
// =======================================================================================
